/*
* Copyright (C) 2021 ~ 2022 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "exefilesprotectiondelegate.h"

//#include <DFontSizeManager>
//#include <DApplicationHelper>

#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QToolTip>

ExeFilesProtectionDelegate::ExeFilesProtectionDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

void ExeFilesProtectionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem itemOption(option);
    if (index.row() % 2 == 0) {
        //DPalette pl(DApplicationHelper::instance()->palette(option.widget));
        QPalette pl = qApp->palette();
        QPainterPath path;
        if (index.column() == TABLE_COL_FILE_NAME) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 12, 12);
            QRect temp_rect(option.rect.left() + 20, option.rect.top(), option.rect.width() - 20, option.rect.height());
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background));
        } else if (index.column() == TABLE_COL_FILE_PATH) {
            painter->fillRect(option.rect, pl.brush(QPalette::Background));
        } else if (index.column() == TABLE_COL_STATUS_NAME) {
            painter->fillRect(option.rect, pl.brush(QPalette::Background));
        } else if (index.column() == TABLE_COL_ACTION_NAME) {
            path.setFillRule(Qt::WindingFill);
            path.addRoundedRect(option.rect, 12, 12);
            QRect temp_rect(option.rect.left(), option.rect.top(), option.rect.width() / 2, option.rect.height());
            path.addRect(temp_rect);
            painter->fillPath(path, pl.brush(QPalette::Background));
        }
    }
    if (itemOption.state & QStyle::State_HasFocus) {
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    }

    // 第0列添加checkbox
    if (TABLE_COL_FILE_NAME == index.column()) {
        painter->save();
        bool isChecked = index.model()->data(index, ROLE_CHECKED_STATUS).toBool();

        QStyleOptionButton checkBox;

        checkBox.state = isChecked ? QStyle::State_On : QStyle::State_Off;
        checkBox.state |= QStyle::State_Enabled;

        QRect tmp = itemOption.rect;
        tmp.setX(tmp.x() + 10);
        tmp.setY(tmp.y() + 14);
        tmp.setWidth(20);
        tmp.setHeight(20);
        checkBox.rect = tmp;
        QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBox, painter);
        painter->restore();

        itemOption.rect = option.rect.adjusted(30, 10, 0, 0);

        painter->save();

        QString fileName = index.model()->data(index, ROLE_FILE_NAME).toString();
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = qApp->font().pixelSize();
        QFont font;
        font.setPixelSize(currentFontSize);
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x() + 10, textRect.y() + 20);
        painter->setFont(font);
        QFontMetrics fontWidth(font);
        fileName = fontWidth.elidedText(fileName, Qt::ElideMiddle, itemOption.rect.width() - 10);

        painter->drawText(textPoint, fileName);
        painter->restore();
    }

    // 第1列添加file path
    if (TABLE_COL_FILE_PATH == index.column()) {
        itemOption.rect = option.rect.adjusted(10, 10, 0, 0);
        painter->save();

        QString sPath = index.model()->data(index, ROLE_FILE_PATH).toString();

        // 字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = qApp->font().pixelSize();
        QFont font;
        font.setPixelSize(currentFontSize);
        painter->setFont(font);

        // 坐标
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x(), textRect.y() + 20);
        QFontMetrics fontWidth(font);
        sPath = fontWidth.elidedText(sPath, Qt::ElideMiddle, itemOption.rect.width() - 10);

        painter->drawText(textPoint, sPath);
        painter->restore();
    }

    // 第2列添加file status
    if (TABLE_COL_STATUS_NAME == index.column()) {
        itemOption.rect = option.rect.adjusted(10, 10, 0, 0);
        painter->save();

        // 文本 - 颜色
        QPen pen;
        QString statusName;
        int nStatus = index.model()->data(index, ROLE_FILE_STATUS).toInt();
        if (nStatus) {
            statusName = tr("Tampered");
            pen.setColor(QColor("#FF5736"));
        } else {
            statusName = tr("Normal");
        }
        painter->setPen(pen);

        // 字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = qApp->font().pixelSize();
        QFont font;
        font.setPixelSize(currentFontSize);
        painter->setFont(font);

        // 坐标
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x(), textRect.y() + 20);
        QFontMetrics fontWidth(font);
        statusName = fontWidth.elidedText(statusName, Qt::ElideMiddle, itemOption.rect.width() - 10);

        painter->drawText(textPoint, statusName);
        painter->restore();
    }

    // 第3列添加file action
    if (TABLE_COL_ACTION_NAME == index.column()) {
        itemOption.rect = option.rect.adjusted(10, 10, 0, 0);
        painter->save();

        // 文本 - 颜色
        QPen pen;
        QString actionName;
        int nStatus = index.model()->data(index, ROLE_FILE_ACTION).toInt();
        if (nStatus) {
            actionName = tr("Trust Current Status");
            pen.setColor(QColor("#0082FA"));
        } else {
            actionName = "";
        }
        painter->setPen(pen);

        // 字体
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = qApp->font().pixelSize();
        QFont font;
        font.setPixelSize(currentFontSize);
        painter->setFont(font);

        // 坐标
        QRect textRect = itemOption.rect;
        QPoint textPoint(textRect.x(), textRect.y() + 20);
        QFontMetrics fontWidth(font);
        actionName = fontWidth.elidedText(actionName, Qt::ElideMiddle, itemOption.rect.width() - 10);

        painter->drawText(textPoint, actionName);
        painter->restore();
    }

    QStyledItemDelegate::paint(painter, itemOption, index);
}

bool ExeFilesProtectionDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QStyleOptionViewItem itemOption(option);
    QMouseEvent *mouse = static_cast<QMouseEvent *>(event);
    if (event->type() == QEvent::MouseButtonRelease && option.rect.contains(mouse->pos())) {
        if (index.column() == TABLE_COL_FILE_NAME) {
            bool checkState = model->data(index, ROLE_CHECKED_STATUS).toBool();
            model->setData(index, !checkState, ROLE_CHECKED_STATUS);
            Q_EMIT sendCheckClickSingal();
        }
    }

    if (index.column() == TABLE_COL_ACTION_NAME && event->type() == QEvent::MouseButtonRelease) {
        QRect rect = itemOption.rect;
        QPoint mousePoint = mouse->pos();
//        int currentFontSize = DFontSizeManager::instance()->fontPixelSize(qApp->font());
        int currentFontSize = qApp->font().pixelSize();
        QRect m_trustRect = QRect(rect.x() + 10, rect.y() + 20, currentFontSize * 20, currentFontSize);
        int nStatus = index.model()->data(index, ROLE_FILE_ACTION).toInt();

        if (nStatus && m_trustRect.contains(mousePoint)) {
            Q_EMIT sendTrustFile(index);
        }
    }
    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

bool ExeFilesProtectionDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::ToolTip) {
        if (index.column() == TABLE_COL_FILE_NAME) {
            QStyleOptionViewItem itemOption(option);
            QRect rect = itemOption.rect;

            QRect filePathRect(rect.x() + 40, rect.y() + 10, itemOption.rect.width() - 50, option.fontMetrics.height());
            QRect fileNameRect(rect.x() + 40, rect.y() + option.fontMetrics.height() + 10,
                               itemOption.rect.width() - 50, option.fontMetrics.height());
            QString tooltip;
            if (filePathRect.contains(event->pos())) {
                tooltip = index.model()->data(index, ROLE_FILE_NAME).toString();
            } else if (fileNameRect.contains(event->pos())) {
                tooltip = index.model()->data(index, ROLE_FILE_NAME).toString();
            } else {
                QWidgetList qwl = QApplication::topLevelWidgets();
                for (QWidget *qw : qwl) {
                    if (QString("QTipLabel") == qw->metaObject()->className()) {
                        qw->close();
                    }
                }
            }
            QToolTip::showText(event->globalPos(), tooltip);
            return true;
        } else if (index.column() == TABLE_COL_FILE_PATH) {
            QStyleOptionViewItem itemOption(option);
            QRect rect = itemOption.rect;

            QRect filePathRect(rect.x() + 40, rect.y() + 10, itemOption.rect.width() - 50, option.fontMetrics.height());
            QRect fileNameRect(rect.x() + 40, rect.y() + option.fontMetrics.height() + 10,
                               itemOption.rect.width() - 50, option.fontMetrics.height());
            QString tooltip;
            if (filePathRect.contains(event->pos())) {
                tooltip = index.model()->data(index, ROLE_FILE_PATH).toString();
            } else if (fileNameRect.contains(event->pos())) {
                tooltip = index.model()->data(index, ROLE_FILE_PATH).toString();
            } else {
                QWidgetList qwl = QApplication::topLevelWidgets();
                for (QWidget *qw : qwl) {
                    if (QString("QTipLabel") == qw->metaObject()->className()) {
                        qw->close();
                    }
                }
            }
            QToolTip::showText(event->globalPos(), tooltip);
            return true;
        }
    }
    return QStyledItemDelegate::helpEvent(event, view, option, index);
}
